<?php  

//创建父类:Member  
class Member{  
  	
  	//创建受保护属性:数组
    protected  static $memberdata = array();  
    
    //当调用的方法不存在或权限不足时，会自动调用__call方法
    public  function __call($func, $arguments){  
  		
  		//explode():用'_'字符串分割为数组
  		//list():将数组元素转为对应的独立变量:$type,$name
        list($type, $name) = explode('_', $func);  
        
        //如何$type字符串不在数组'set'和'get'中任何一个
        //或者$name为空的话,则调用的方法名称不正确,直接返回'空';  
        if(!in_array($type, array('set','get')) || $name==''){  
            return '';  
        }  
  		
  		//获取调用当前方法的类名
  		//即:当前方法静态绑定的类名: 如 User
        $feature = get_called_class();  
        
          //判断$type值
          switch($type){ 
          	//如果$type = 'set',则是给属性$memeberdata赋值 
            case 'set':
            	//将当前方法的参数数组的值$arguments[0]
            	//赋给属性 $memberdata[$feature][$name]:注意是二维数组
            	//当前方法只有一个值:$arguments[0]
                self::$memberdata[$feature][$name] = $arguments[0];  
                break;  
  			
  			//如果$type = 'get',则是获取属性$memeberdata的值 
            case 'get': 
            
            	//如果 self::$memberdata[$feature][$name]存在则返回该值,否则返回:空
                return isset(self::$memberdata[$feature][$name])? self::$memberdata[$feature][$name] : '';  
                break;    
            default:  
        }        
    }    
}  
  
//创建子类:User,继承自:Member类
class User extends Member{  
  
  	//定义公共方法:show(),用来输出数据
    public  function show(){  
  		
  		//获取调用当前方法的类名,如:User
        $feature = get_called_class();  
  		
  		//如果self::$memberdata[$feature]属性存在
        if(self::$memberdata[$feature]){ 

        	//输出与当前类所对应的$memberdata[$feature]属性值 
            foreach(self::$memberdata[$feature] as $key=>$member){  
                echo $key.':'.$member.'<br>';  
            }  
        }  
    }    
}  
  
 //创建子类:Profession,继承自:Member类 
class Profession extends Member{  
  
  	//定义公共方法:show(),用来输出数据
    public  function show(){  
  		
  		//获取调用当前方法的类名,如:Profession
        $feature = get_called_class();  
  		
  		//如果self::$memberdata[$feature]属性存在
        if(self::$memberdata[$feature]){  
        	//输出与当前类所对应的$memberdata[$feature]属性值 
            foreach(self::$memberdata[$feature] as $key=>$member){  
                echo $key.':'.$member.'<br>';  
            }  
        }  
    }    
}  

//调用set_name(),set_age()
//当前类User和父类中都没有set_name方法,于是自动触发父类__call()方法
//父类Member中的__call($func,$arguments)是系统魔术方法
//在__call方法中,方法名set_name转换为变量$type和$name
//并根据$type,完成属性的动态赋值或读取操作
//set_name(),set_age()分别完成了对$memberdata[$feature]属性的动态赋值操作

$user = new User();
$user -> set_name('ThinkPHP');  
$user -> set_age(10);  
$user -> show();  

//调用set_profession(),set_price()
//当前类User和父类中都没有set_name静态方法,于是自动触发父类__callStatic()方法
//父类Member中的__callStatic($func,$arguments)是系统魔术方法
//在__callStatic方法中,方法名set_name转换为变量$type和$name
//并根据$type,完成属性的动态赋值或读取操作
//set_name(),set_age()分别完成了对$memberdata[$feature]属性的动态赋值操作  

$profession = new Profession();
$profession -> set_lession('模型');  
$profession -> set_teacher('理达课堂');  
$profession -> show();




class Father{
    //父类中的say方法
    public  function say(){
        return 'PHP';
    }

    public static function demo(){
        $obj = new static();

        //猜想一下,应该调用哪个say方法呢？
        return $obj -> say();
    }
}

class Sub extends Father
{
    //子类中的say方法
    public function say(){
        return 'ThinkPHP5';
    }
}

echo Father::demo();  //返回: PHP

echo Sub::demo(); //返回:ThinkPHP